<?php

/**
 * This file is part of the Codizer package.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @copyright   Copyright (c) 2010 Advisa (http://www.advisa.fr)
 * @author      Codizer Core Team <team@codizer.org>
 * @package     Codizer
 */

class f_logs_Logger
{
	private static $instance;
	
	private $loggingLevel = 0;
	
	const DEBUG 	= 10;
	const ALERT 	= 8;
	const NOTICE	= 2;
	const PROD	= 0;

	private $firePHPLogger;
	
	/**
	 * @return f_logs_Logger
	 */
	private function __construct()
	{
		$parameters = f_loader_Config::getInstance()->getParameters("default");
		
		if($parameters['loggingLevel'] != "")
		{
			$logingLevel = constant("self::".strtoupper($parameters['loggingLevel']));
			$this->loggingLevel = $logingLevel;
		}
		
		if(isset($parameters['enableFirePHP']) && $parameters['enableFirePHP'] == 1)
		{
			$firePHPLoggerFile = FRAMEWORK_HOME.DS."logs".DS."FirePHPCore".DS."FirePHP.class.php";
			
			if(is_file($firePHPLoggerFile))
			{
				require_once($firePHPLoggerFile);
				$this->firePHPLogger = FirePHP::getInstance(true);
			}
		}
		
		return $this;
	}
	
	/**
	 * Get singleton instance
	 *
	 * @return f_logs_Logger
	 */
	public static function getInstance()
	{
		if(self::$instance === null)
		{
			self::$instance = new self();
		}
		return self::$instance;
	}
	
	/**
	 * Get FirePHP Logger
	 *
	 * @return FirePHP
	 */
	public function getFirePHPLogger()
	{
		return $this->firePHPLogger;
	}
	
	/**
	 * Set the logging level to use
	 *
	 * @param integer $level
	 */
	public function setLoggingLevel($level)
	{
		$this->loggingLevel = $level;
	}
	
	/**
	 * Get the current logging level
	 *
	 * @return integer
	 */
	public function getLoggingLevel()
	{
		return $this->loggingLevel;
	}
	
	/**
	 * write a message in the error log
	 *
	 * @param string $message
	 */
	public function errorLog($message)
	{
		if($this->loggingLevel > self::NOTICE)
		{
			$this->putInLog("errors", "[-------] [ERR] ".$message);
		}
	}
	
	/**
	 * write a message in the notice log
	 *
	 * @param string $message
	 */
	public function noticeLog($message)
	{
		if($this->loggingLevel >= self::NOTICE)
		{
			$this->putInLog("notices", "[-------] [NOT] ".$message);
		}
	}
	
	/**
	 * write a message in the cache log
	 *
	 * @param string $message
	 */
	public function cacheLog($message, $time = null)
	{
		if(is_null($time)) $time = "-------";
		$time = str_pad($time, 7, "0");
		
		if($this->loggingLevel >= self::NOTICE)
		{
			if(floatval($time) > 0.10)
			{
				$time = "[".$time."]#";
			}
			else
			{
				$time = "[".$time."] ";
			}					
			$this->putInLog("cache", $time."[CAE] ".$message);
		}
	}	
	
	/**
	 * write a message in the sql log
	 *
	 * @param string $message
	 */
	public function sqlLog($message, $time = null)
	{
		if(is_null($time)) $time = "-------";
		$time = str_pad($time, 7, "0");
		if($this->loggingLevel == self::DEBUG)
		{
			if(floatval($time) > 0.10)
			{
				$time = "[".$time."]#";
			}
			else
			{
				$time = "[".$time."] ";
			}			
			$this->putInLog("sql", $time."[SQL] \t".$message);			
		}
	}
	
	/**
	 * write a message in the action log
	 *
	 * @param string $message
	 */
	public function actionLog($message, $time = null)
	{
		if(is_null($time)) $time = "-------";
		$time = str_pad($time, 7, "0");
		if($this->loggingLevel == self::DEBUG)
		{
			if(floatval($time) > 0.40)
			{
				$time = "[".$time."]#";
			}
			else
			{
				$time = "[".$time."] ";
			}			
			$this->putInLog("actions", $time."[ACT] ".$message);			
		}
	}
	
	/**
	 * write a message in the template log
	 *
	 * @param string $message
	 */
	public function templateLog($message, $time = null)
	{
		if(is_null($time)) $time = "-------";
		$time = str_pad($time, 7, "0");
		if($this->loggingLevel == self::DEBUG)
		{
			if(floatval($time) > 0.20)
			{
				$time = "[".$time."]#";
			}
			else
			{
				$time = "[".$time."] ";
			}
			
			$this->putInLog("template", $time."[TPL] \t".$message);			
		}
	}	
	
	/**
	 * write a message in the exception log
	 *
	 * @param string $message
	 */
	public function exceptionLog($message)
	{
		$this->putInLog("exception", "[-------] [EXC] ".$message);
	}
	
	/**
	 * write a message in the action log
	 *
	 * @param string $message
	 */
	public function requestLog($message)
	{
		if($this->loggingLevel == self::DEBUG)
		{
			$this->putInLog("request", "[-------] ========= Request ".$message." =========");		
		}
	}
	
	/**
	 * Generic method to write a message in a log file 
	 *
	 * @param string $logFileName
	 * @param string $message
	 */
	private function putInLog($logFileName, $message)
	{
		$logPath = WEBAPP_DIR.DS."logs".DS;
		
		$logFileName = str_replace(".log", "", $logFileName);
		
		$fileHandler = fopen($logPath.$logFileName.".log", "a+");

		// if filesize > 10Mo
		if(filesize($logPath.$logFileName.".log") >= 10240000)
		{
			$nbFiles = count(glob($logPath.$logFileName.".*"));
			$nbFiles = str_pad($nbFiles, 3, "0", STR_PAD_LEFT);
			
			copy($logPath.$logFileName.".log", $logPath.$logFileName.".".$nbFiles.".log");
			unlink($logPath.$logFileName.".log");
		}
		
		fwrite($fileHandler, "[".date("Y-m-d H:i:s")."] ".$message."\n");
		
		if($logFileName != "allinone")
		{
			$this->putInLog("allinone", $message);
		}
	}
} 